﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using X3DXNA.interfaces;
using X3DXNA.utils;
using X3DXNA.X3DSchema;

namespace X3DXNA.core.CustomNodes
{
    public class MyTransform : IRoutable
    {

        #region Private Fields

        Vector3 bboxCenter;
        Vector3 bboxSize;

        bool isRouted;

        #endregion

        #region Public Properties

        public String DEF { get; set; }

        /// <summary>
        /// Divertente proprietà: quando un transform non è ROUTED, non è detto che l'eventuale shape al suo interno
        /// sia statica. Infatti un Transform Padre potrebbe essere dinamico! Dunque, se l'attuale nodo non è segnato
        /// come ROUTED, controlliamo i suoi "predecessori", che a loro volta, a catena, faranno lo stesso.
        /// </summary>
        public bool IsRouted
        {
            get
            {
                if (isRouted == true)
                    return isRouted;
                else if (previousTransformation != null)
                    return previousTransformation.IsRouted;
                else
                    return false;
            }
            set
            {
                isRouted = value;
            }
        }

        public Vector3 translation { get; set; }
        public Quaternion rotation { get; set; }
        public Vector3 center { get; set; }
        public Vector3 scale { get; set; }
        public Quaternion scaleOrientation { get; set; }

        public MyTransform previousTransformation { get; set; }

        #endregion

        #region Contructors

        public MyTransform(String DEF)
        {
            this.DEF = DEF;
            this.translation = Vector3.Zero;
            this.rotation = Quaternion.Identity;
            this.center = Vector3.Zero;
            this.scale = Vector3.One;
            this.scaleOrientation = Quaternion.Identity;
            this.bboxCenter = Vector3.Zero;
            this.bboxSize = new Vector3(-1, -1, -1);
        }

        #endregion

        #region Public Methods

        public Matrix getMatrixTransformation
        {
            get
            {
                Matrix transformation = Matrix.CreateScale(scale) *
                                        Matrix.CreateFromQuaternion(rotation) *
                                        Matrix.CreateTranslation(translation);

                if (previousTransformation != null)
                    return transformation * previousTransformation.getMatrixTransformation;
                else
                    return transformation;
            }
        }

        #endregion

        #region Public Static Builder

        public static MyTransform getNewTransform(Transform t)
        {
            MyTransform newTransformToReturn = new MyTransform(t.DEF);

            if (t.translation != null)
                newTransformToReturn.translation = utility.stringToVector3Translation(t.translation);
            if (t.rotation != null)
                newTransformToReturn.rotation = utility.vector4ToQuaternionRotation(utility.stringToVector4Rotation(t.rotation));
            if (t.scale != null)
                newTransformToReturn.scale = utility.stringToVector3Scalation(t.scale);

            #warning Implementare anche gli altri campi! (center etc).
 
            return newTransformToReturn;
        }

        #endregion

    }
}
